<template>
  <MyDrawer ref="MyDrawerRef" title="API操作" @submit="submit" :disabled="false" width="30%">
    <el-form :model="drawerProps.rowData" :rules="rules" label-width="120" ref="formRef">
      <el-form-item label="api名称" prop="apiName">
        <el-input v-model="drawerProps.rowData.apiName"></el-input>
      </el-form-item>
      <el-form-item label="api路径" prop="apiPath">
        <el-input v-model="drawerProps.rowData.apiPath"></el-input>
      </el-form-item>
      <el-form-item label="需要审核的角色">
        <el-cascader
          :options="(roleList as any)"
          :props="props"
          v-model="nowCheck"
          :show-all-levels="false"
          clearable
        ></el-cascader>
      </el-form-item>
      <el-form-item label="排序">
        <el-input-number v-model="drawerProps.rowData.sort"></el-input-number>
      </el-form-item>
      <el-form-item label="api分组" prop="apiGroup">
        <el-input v-model="drawerProps.rowData.apiGroup"></el-input>
      </el-form-item>
      <el-form-item label="api类型" prop="apiType">
        <el-select v-model="drawerProps.rowData.apiType">
          <el-option v-for="(p, index) in ApiType" :key="index" :value="p" :label="p"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="备注" prop="remark">
        <el-input v-model="drawerProps.rowData.remark"></el-input>
      </el-form-item>
    </el-form>
  </MyDrawer>
</template>

<script setup lang="ts" name="ApiDrawer">
import MyDrawer from "@/components/MyDrawer/index.vue";
import { reactive, ref, onBeforeMount } from "vue";
import { Api } from "@/api/interface/api";
import { CascaderProps, ElMessage, FormInstance, FormRules } from "element-plus";
import { CheckPath } from "@/utils/eleValidate";
import { GetRoleList } from "@/api/modules/role";
import { Role } from "@/api/interface/role";

interface DrawerProps {
  api?: (params: any) => Promise<any>;
  rowData: Api.Option;
  getTable?: () => Promise<any>;
}

const initData: Api.Option = {
  apiGroup: "",
  apiName: "",
  apiPath: "",
  apiType: "GET",
  sort: 100,
  remark: ""
};

const ApiType: any[] = ["GET", "POST", "PUT", "DELETE"];

const drawerProps = ref<DrawerProps>({
  rowData: JSON.parse(JSON.stringify(initData))
});

const MyDrawerRef = ref<InstanceType<typeof MyDrawer> | null>();

const acceptParams = (params: DrawerProps) => {
  drawerProps.value = params;
  if (!params.rowData) {
    drawerProps.value.rowData = JSON.parse(JSON.stringify(initData));
  }
  if (params.rowData.auditRequire) {
    const list = drawerProps.value.rowData.auditRequire
      ?.split(",")
      .map(e => parseInt(e))
      .filter(e => !isNaN(e));
    nowCheck.value = list as any;
  } else {
    nowCheck.value = [];
  }
  MyDrawerRef.value?.acceptParams();
};

// ----------规则
const checkType = (rule: any, value: string, callback: any) => {
  if (ApiType.includes(value.toLocaleUpperCase())) {
    callback();
  } else {
    return callback(new Error("无效的请求类型"));
  }
};

const rules = reactive<FormRules>({
  apiName: [
    { required: true, message: "接口名称必须" },
    { max: 20, min: 1, message: "字符1-20之间" }
  ],
  apiPath: [
    { required: true, message: "接口路径必须" },
    { min: 2, max: 200, message: "字符2-200之间" },
    { validator: CheckPath }
  ],
  apiGroup: [
    { required: true, message: "分组不可为空" },
    { max: 20, min: 1, message: "字符1-20之间" }
  ],
  apiType: [{ required: true, message: "类型不可为空" }, { validator: checkType }],
  remark: [{ max: 300, min: 0, message: "字符不超过300个" }]
});

// ---------------表单
const formRef = ref<FormInstance>();

const submit = () => {
  formRef.value?.validate(async valid => {
    if (valid) {
      if (nowCheck.value.length !== 0) {
        drawerProps.value.rowData.auditRequire = "," + nowCheck.value[nowCheck.value?.length - 1].join(",") + ",";
      } else {
        drawerProps.value.rowData.auditRequire = "";
      }
      await drawerProps.value.api!(drawerProps.value.rowData);
      ElMessage.success("成功!");
      await drawerProps.value.getTable!();
      MyDrawerRef.value?.close();
    }
  });
};

const roleList = ref<Role.Option[]>();
const props = ref<CascaderProps>({
  multiple: true,
  value: "id",
  label: "roleName",
  children: "roles",
  checkStrictly: true
});
const nowCheck = ref<number[][]>([]);
onBeforeMount(async () => {
  const { data } = await GetRoleList();
  roleList.value = data as Role.Option[];
});

defineExpose({
  acceptParams
});
</script>

<style></style>
